package com.pb.metadata.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pb.infra.oth.util.JwtTokenConfig;
import com.pb.infra.auth.mapper.CommonMapper;
import com.pb.metadata.mapper.FieldManagementMapper;
import com.pb.infra.oth.entity.common.Page;
import com.pb.infra.oth.entity.common.Result;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 字段管理
 * @author liaohaoyuan
 * @date 20210301
 */
@Service
public class FieldManagementService {

    /**
     * 字段表DAO映射对象
     */
    @Resource
    private FieldManagementMapper fieldManagementMapper;

    /**
     * 公共接口
     */
    @Resource
    private CommonMapper commonMapper;

    /**
     * jwttoken配置类
     */
    @Resource
    private JwtTokenConfig jwtTokenConfig;

    /**
     * 查询字段分页数据
     * @param map 查询参数
     * @param page 页码
     * @return
     */
    public Result select(Map<String, Object> map, Page page){
        if (page != null && page.getPageIndex() != null && page.getPageSize() != null) {
            PageHelper.startPage(page.getPageIndex(), page.getPageSize());
        }
        map.put("columnName",map.get("columnName").toString().toUpperCase());
        List<Map<String, Object>> list = fieldManagementMapper.select(map);
        return Result.ok(new PageInfo(list).getTotal(), list);
    }

    /**
     * 查询字段
     * @param map 查询参数
     * @return
     */
    public List selectList(Map<String, Object> map){
        List<Map<String, Object>> list = fieldManagementMapper.select(map);
        return list;
    }

    /**
     * 字段管理新建数据
     * @param paramMap 保存数据
     * @return
     */
    @Transactional
    public Result insert(Map<String, Object> paramMap, HttpServletRequest request){
        String token = request.getHeader(jwtTokenConfig.getHeader());
        Claims claims = jwtTokenConfig.getClaimByToken(token);
        String userId = (String)claims.get(jwtTokenConfig.getSub());
        paramMap.put("userId", userId);
        paramMap.put("columnId",  UUID.randomUUID().toString().replace("-", ""));
        paramMap.put("columnName",paramMap.get("columnName").toString().toUpperCase());
        paramMap.put("debugFlag","1");
        paramMap.put("deleteFlag","0");
        paramMap.put("recordSts","FREE");
        paramMap.put("createUser",paramMap.get("userId"));
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        paramMap.put("createTime",format.format(new Date()));
        int count=fieldManagementMapper.getParamColumnCount(paramMap);
        if(count>0){
            paramMap.put("updateUser",paramMap.get("userId"));
            paramMap.put("updateTime",format.format(new Date()));
            fieldManagementMapper.updateByParam(paramMap);
        }else{
            fieldManagementMapper.insert(paramMap);
        }
        return Result.OK_EMPTY;
     }

    /**
     * 字段修改
     * @return
     */
    @Transactional
     public  Result update(Map<String, Object> paramMap, HttpServletRequest request){
        String token = request.getHeader(jwtTokenConfig.getHeader());
        Claims claims = jwtTokenConfig.getClaimByToken(token);
        String userId = (String)claims.get(jwtTokenConfig.getSub());
        paramMap.put("userId", userId);
        paramMap.put("updateUser",paramMap.get("userId"));
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        paramMap.put("updateTime",format.format(new Date()));
        paramMap.put("columnName",paramMap.get("columnName").toString().toUpperCase());
        fieldManagementMapper.update(paramMap);
        return Result.OK_EMPTY;
     }

    /**
     * 获取数据库数据
     * @return
     */
     public Result getDatabaseUserList(){
         List<Map<String,Object>> list =fieldManagementMapper.getDatabaseUserList();
         return Result.ok(list);
     }

    /**
     * 获取数据库数据表头提示
     * @return
     */
    public String getDatabaseUserStr(){
        List<Map<String,Object>> list =fieldManagementMapper.getDatabaseUserList();
        String userString = "数据库用户:";
        for(Map map : list){
            userString = userString + map.get("cnName")+"，";
        }
        return userString;
    }

    /**
     * 获取字段类型码值
     * @return
     */
    public Result getColumnTypeList(){
        List<Map<String,Object>> list =fieldManagementMapper.getColumnTypeList();
        return Result.ok(list);
    }
    /**
     * 获取字段用途码值
     * @return
     */
    public Result getColumnUseList(){
        List<Map<String,Object>> list =fieldManagementMapper.getColumnUseList();
        return Result.ok(list);
    }

    /**
     * 删除字段
     * @param list
     */
     public void delete(List<String> list){
        this.fieldManagementMapper.delete(list);
    }

    /**
     * 启用停用字段
     * @param paramMap
     */
    @Transactional
    public void startOrStop( List<Map<String,Object>> paramMap){
        for (Map<String,Object> map:paramMap){
            String str=(String) map.get("activeFlag");
            map.put("activeFlag","1".equals(str)?"0":"1");
            fieldManagementMapper.startOrStop(map);
        }
    }

    /**
     * 锁定码表信息
     * @param map 请求参数
     */
    @Transactional
    public void lockedDate(List<String> map) {
        fieldManagementMapper.lockedDate(map);
    }

    /**
     * 提交码表信息
     * @param map 请求参数
     */
    @Transactional
    public void freeDate(List<String> map) {
        fieldManagementMapper.freeDate(map);
    }

    /**
     * 导入
     * @param data
     */
    @Transactional
    public String importExcel(List<List<Map<String,Object>>> data){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        String date = df.format(calendar.getTime());
        String msg="";
        StringBuilder stringBuffer = new StringBuilder();
        List<Map<String,Object>> addList =new ArrayList<>();
        List<Map<String,Object>> updateList=new ArrayList<>();
        List<Map<String, Object>> dataBaseUserList=null;//数据库用户
        List<Map<String, Object>> activeFlagList=fieldManagementMapper.getActiveFlagList();//有效标识
        List<Map<String, Object>> recordStsList=fieldManagementMapper.getRecordStsList();//锁定标识
        List<Map<String, Object>> columnUseList=fieldManagementMapper.getColumnUseList();//字段用途
        List<Map<String, Object>> columnTypeList=fieldManagementMapper.getColumnTypeList();//字段类型
        boolean fialFlag=false;
        for (int i = 0; i <data.size() ; i++) {
            List<Map<String,Object>> list =data.get(i);
            int n=2;
            for (Map<String,Object> map : list) {
                boolean msgFlag=false;
                StringBuffer sbf=new StringBuffer();
                if(!msgFlag){
                    sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第<b>"+(n)+"</b>行数据:<br/>");
                }
                map.put("debugFlag","1");
                map.put("deleteFlag","0");
                map.put("date",date);
                /*map.put("appIdP",appIdP);
                String appDesc=(String) map.get("appDesc");
                if (i==0){
                    appIdList = fieldManagementMapper.getAppIdList(map);
                }
                for(Map<String,Object> appIdMap : appIdList){
                    if (appDesc.equals((String) appIdMap.get("cnName"))){
                        map.put("appId",(String) appIdMap.get("code"));
                        break;
                    }else{
                        if (i==appIdList.size()-1){
                            msgFlag=true;
                            sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<应用名称></b>应用名称输入错误");
                        }
                    }
                }*/
                /*String appId=(String)map.get("appId");
                if("".equals(appId)||appId==null){
                    msgFlag=true;
                    sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<应用名称></b>"+"“"+appDesc+"”不在实际应用名称数据集中");
                }*/

                String databaseUser=(String) map.get("databaseUser");
                if (i==0){
                    dataBaseUserList = fieldManagementMapper.getDataUserList();
                }
                for(Map<String,Object> dataBaseUserMap : dataBaseUserList){
                    if (databaseUser.equals((String) dataBaseUserMap.get("cnName"))){
                        map.put("databaseUserId",(String) dataBaseUserMap.get("code"));
                        break;
                    }else{
                        if (i==dataBaseUserList.size()-1){
                            msgFlag=true;
                            sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<数据库用户></b>数据库用户输入错误");
                        }
                    }
                }
                if(map.get("databaseUserId")==null){
                    msgFlag=true;
                    sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<数据库用户></b>数据库用户"+"“"+databaseUser+"“不在实际数据用户数据集中");
                }
                String columnName=(String)map.get("columnName");
                Pattern pattern = Pattern.compile("^[a-zA-Z]+[a-zA-Z0-9_]*(?<![_])$");
                if(!pattern.matcher(columnName).matches()){
                    msgFlag=true;
                    sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<字段名称></b>首位必须是字母,可包含下划线、数字");
                }
                map.put("columnName",(String)((String) map.get("columnName")).toUpperCase());

                String recordStsDesc=(String) map.get("recordStsDesc");
                for(Map<String,Object> recordStsMap : recordStsList){
                    if (recordStsDesc.equals((String) recordStsMap.get("cnName"))){
                        map.put("recordSts",(String) recordStsMap.get("code"));
                        break;
                    }else{
                        if (i==recordStsList.size()-1){
                            msgFlag=true;
                            sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<锁定标识></b>锁定标识输入错误");
                        }
                    }
                }
                if("".equals(map.get("recordSts"))||map.get("recordSts")==null){
                    msgFlag=true;
                    sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<锁定标识></b>"+"“"+recordStsDesc+"”不在实际锁定标识数据集中");
                }

                String activeDesc=(String) map.get("activeDesc");
                for(Map<String,Object> activeMap : activeFlagList){
                    if (activeDesc.equals((String) activeMap.get("cnName"))){
                        map.put("activeFlag",(String) activeMap.get("code"));
                        break;
                    }else{
                        if (i==activeFlagList.size()-1){
                            msgFlag=true;
                            sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<有效标识></b>有效标识输入错误");
                        }
                    }
                }
                if("".equals(map.get("activeFlag"))||map.get("activeFlag")==null){
                    msgFlag=true;
                    sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<有效标识></b>"+"“"+activeDesc+"“不在实际有效标识数据集中");
                }

                String columnUseDesc=(String) map.get("columnUseDesc");
                for(Map<String,Object> columnUseMap : columnUseList){
                    if (columnUseDesc.equals((String) columnUseMap.get("cnName"))){
                        map.put("columnUse",(String) columnUseMap.get("columnUse"));
                        break;
                    }else{
                        if (i==columnUseList.size()-1){
                            msgFlag=true;
                            sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<字段用途></b>字段用途输入错误");
                        }
                    }
                }
                if("".equals(map.get("columnUse"))||map.get("columnUse")==null){
                    msgFlag=true;
                    sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<字段用途></b>"+"“"+columnUseDesc+"“不在实际字段用途数据集中");
                }

                String columnTypeDesc=(String) map.get("columnTypeDesc");
                for(Map<String,Object> columnTypeMap : columnTypeList){
                    if (columnTypeDesc.equals((String) columnTypeMap.get("cnName"))){
                        String columnType=(String) columnTypeMap.get("columnType");
                        map.put("columnType",columnType);
                        break;
                    }else{
                        if (i==columnTypeList.size()-1){
                            msgFlag=true;
                            sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<字段类型></b>字段类型输入错误");
                        }
                    }
                }
                if("".equals(map.get("columnType"))||map.get("columnType")==null){
                    msgFlag=true;
                    sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<字段类型></b>"+"“"+columnTypeDesc+"”不在实际字段类型数据集中");
                }

                if (msgFlag){
                    msg="<span style='color:red;font-weight:bold;'>======>导入失败</span>(请您根据提示修正数据后再完成导入操作)<span style='color:red;font-weight:bold;'><=====</span> <br/>";
                    msg=msg+stringBuffer.append(sbf.toString());
                    fialFlag=true;
                }else{
                    if(!fialFlag){
                        msg= "**********   <span style='color:green;font-weight:bold;'>导入结果：成功</span>   ********** <br/><br/>字段管理共计导入 <span style='color:blue;font-weight:bold;'>"+ list.size() + "</span> 条数据";
                        Map<String,Object> paraMap=new HashMap<String,Object>();
                        String databaseUserId=(String)map.get("databaseUserId");
                        paraMap.put("databaseUserId",databaseUserId);
                        paraMap.put("columnName",columnName.toString().toUpperCase());
                        List<Map<String,Object>> dataList = fieldManagementMapper.getDataSizeList(paraMap);
                        if (dataList.size()>0){
                            Map<String,Object> columnMap=dataList.get(0);
                            map.put("columnId",columnMap.get("COLUMN_ID"));
                            updateList.add(map);
                        }else {
                            map.put("columnId",  UUID.randomUUID().toString().replace("-", ""));
                            addList.add(map);
                        }
                    }
                }
                n++;
            }
        }
        if (addList.size() > 0) {
            try{
                fieldManagementMapper.addFieldManagement(addList);
            }catch  (Exception e){
                e.printStackTrace();
                msg="<span style='color:red;font-weight:bold;'>======>导入失败</span><span style='color:red;font-weight:bold;'><=====</span> <br/>(违反唯一主键约束，数据库用户，字段名称，调试标志的值不能一样，请修正数据后重新导入)";
                return msg;
            }
        }
        if(updateList.size()>0){
            fieldManagementMapper.updateFieldManagement(updateList);
        }
        return msg;
    }
}
